/*
 * Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.weike.bsp.security.authentication.jwt

import org.springframework.security.authentication.BadCredentialsException
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.security.core.userdetails.ReactiveUserDetailsService
import org.springframework.stereotype.Component
import org.springframework.web.server.ServerWebExchange
import org.springframework.web.server.WebFilter
import org.springframework.web.server.WebFilterChain
import reactor.core.publisher.Mono

/**
 * 通过获取token,获取用户的相关信息
 * @author tiger
 * @see UsernamePasswordAuthenticationToken
 *
 * @see org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
 *
 * @see org.springframework.security.web.authentication.www.BasicAuthenticationFilter
 *
 * @since 5.0
 *
 * 使用jwt鉴权时，直接根据jwt token 获取到username,然后根据username获取用户信息，所以不需要判定密码
 */
@Component
class JwtAuthenticationFilter(
        private val userDetailsService: ReactiveUserDetailsService,
) : WebFilter {

//    protected var authenticationDetailsSource: AuthenticationDetailsSource<HttpServletRequest, *> = WebAuthenticationDetailsSource()

    private val tokenExtractor = JwtTokenExtractor()

//    @Throws(AuthenticationException::class, ServletException::class, IOException::class)
//    override fun doFilterInternal(@NonNull request: HttpServletRequest, @NonNull response: HttpServletResponse, @NonNull filterChain: FilterChain) {
//        val token = tokenExtractor.extract(request)
//
//        if (token != null) {
//            val claims = JwtTokenUtils.getInstance().getClaims(token)
//            try {
//                JwtTokenUtils.getInstance().check(claims)
//            } catch (e: Exception) {
//                throw BadCredentialsException(e.message)
//            }
//            val username = claims.subject
//            val at = accessTokenRedisService.findByUsername(username) ?: throw BadCredentialsException("token 无效")
//            if (at.isExpired) {
//                throw BadCredentialsException("token 过期")
//            }
//            try {
//                val ud = userDetailsService.loadUserByUsername(username)
//                val authRequest = JwtAuthenticationToken(ud, token, ud.authorities, at)
//                setDetails(request, authRequest)
//                SecurityContextHolder.getContext().authentication = authRequest
//            } catch (e: AuthenticationException) {
//                logger.debug(e)
//            }
//        }
//
//        // 只要不报异常，就继续下面的流程
//        filterChain.doFilter(request, response)
//    }

//    protected fun setDetails(request: HttpServletRequest, authRequest: UsernamePasswordAuthenticationToken) {
//        authRequest.details = authenticationDetailsSource.buildDetails(request)
//    }

    override fun filter(exchange: ServerWebExchange, chain: WebFilterChain): Mono<Void> {
        val token = tokenExtractor.extract(exchange.request)

//        if (token != null) {
//            val claims = JwtTokenUtils.getInstance().getClaims(token)
//            try {
//                JwtTokenUtils.getInstance().check(claims)
//            } catch (e: Exception) {
//                throw BadCredentialsException(e.message)
//            }
//            val username = claims.subject
//        }

        return chain.filter(exchange)
    }

}
